#ifndef KINECTSENSOR_H
#define KINECTSENSOR_H

// Windows Header Files
#include <windows.h>

#include <Shlobj.h>


// Kinect Header files
#include <Kinect.h>


#include <QObject>
#include <QString>
#include <QMouseEvent>
#include <QApplication>
#include <QWidget>
#include <QPoint>
#include <QDebug>
#include <QWindow>
#include <QCursor>
#include <QBitmap>

class KinectSensor : public QObject
{
    Q_OBJECT
public:
    explicit KinectSensor(QObject *parent = 0){
        m_pKinectSensor=NULL;
        m_pCoordinateMapper=NULL;
        m_pBodyFrameReader=NULL;
        currentPBody=NULL;


        InitializeDefaultSensor();

//        bitmap=new QBitmap("qrc:/imgSource/cursor.png");
        cursor=new QCursor(Qt::CrossCursor);
        cursor->setShape(Qt::DragMoveCursor);
    }

    /// <summary>
    /// Main processing function
    /// </summary>
     Q_INVOKABLE void updatebody();

    /// <summary>
    /// Initializes the default Kinect sensor
    /// </summary>
    /// <returns>S_OK on success, otherwise failure code</returns>
    Q_INVOKABLE HRESULT                 InitializeDefaultSensor();

    /// <summary>
    /// Handle new body data
    /// <param name="nTime">timestamp of frame</param>
    /// <param name="nBodyCount">body data count</param>
    /// <param name="ppBodies">body data in frame</param>
    /// </summary>
//    Q_INVOKABLE void                    ProcessBody(INT64 nTime, int nBodyCount, IBody** ppBodies);

    Q_INVOKABLE bool getCurrentBody(IBody **ppbodies);
    Q_INVOKABLE  void getBodyJoint();
    Q_INVOKABLE  void mapJointsToXYCoord();


    Q_INVOKABLE   QString getLeftHandState();
    Q_INVOKABLE  QString getRightHandState();

    Q_INVOKABLE float getLeftHandx(){
        return leftHandPoint.X;
    }
    Q_INVOKABLE float getLeftHandy(){
        return leftHandPoint.Y;
    }
    Q_INVOKABLE float getRightHandx(){
        return rightHandPoint.X;
    }
    Q_INVOKABLE float getRightHandy(){
        return rightHandPoint.Y;
    }

    Q_INVOKABLE void setWinPos(int x,int y){
        winx=x;
        winy=y;
    }

    Q_INVOKABLE void refreshMousePos(int mousex,int mousey){
        cursor->setPos(mousex,mousey);
    }
    Q_INVOKABLE void sendMouseLeftPressEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
        QMouseEvent *mevent=new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        QApplication::sendEvent(QApplication::focusWindow(),mevent);
        delete mevent;
    }
    Q_INVOKABLE void sendMouseLeftReleaseEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
        QMouseEvent *mevent=new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
        QApplication::sendEvent(QApplication::focusWindow(),mevent);
        delete mevent;
    }

    Q_INVOKABLE void sendMouseDragEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
         QMouseEvent *mevent=new QMouseEvent(QEvent::DragMove, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
         QApplication::sendEvent(QApplication::focusWindow(),mevent);
         delete mevent;
    }

    Q_INVOKABLE void sentMouseRightPressEvent(){

    }
    Q_INVOKABLE void sentMouseRightReleaseEvent(){

    }
//    Q_INVOKABLE void sentMouseMoveEvent(){
//        QApplication::sendEvent(QApplication::focusObject(),mouseMoveEvent);
//    }
    Q_INVOKABLE void setnMouseLeftClickEvent(){
        QPoint pos;
        pos.setX(cursor->pos().x());
        pos.setY(cursor->pos().y());
         QMouseEvent *mevent=new QMouseEvent(QEvent::MouseButtonDblClick, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
         QApplication::sendEvent(QApplication::focusWindow(),mevent);
         delete mevent;
//        QApplication::sendEvent(QApplication::focusObject(),mouseLeftClickEvent);
    }

    Q_INVOKABLE double getGuestureWidth(){
        return (topRightJoint.Position.X-topLeftJoint.Position.X);
    }
    Q_INVOKABLE double getCurrentMousePositionx(){
        return (rightHandJoint.Position.X-topRightJoint.Position.X)/(((topRightJoint.Position.X-topLeftJoint.Position.X)));
    }
    Q_INVOKABLE double getCurrentMousePositiony(){
        return (rightHandJoint.Position.Y-((bottomRightJoint.Position.Y+topRightJoint.Position.Y)/2+topRightJoint.Position.Y)/2)/(neckJoint.Position.Y-((bottomRightJoint.Position.Y+topRightJoint.Position.Y)/2+topRightJoint.Position.Y)/2);
    }

    Q_INVOKABLE bool hasTrackingBody(){
        if(currentPBody){
            return true;
        }else{
            return false;
        }
    }

signals:

public slots:

private:

    // Current Kinect
    IKinectSensor*          m_pKinectSensor;
    ICoordinateMapper*      m_pCoordinateMapper;

    IBody *currentPBody;

    //hand state
    HandState leftHandState=HandState_Unknown;
    HandState rightHandState=HandState_Unknown;

    //hand joint (get both hands's position)
    Joint leftHandJoint;
    Joint rightHandJoint;

    Joint topRightJoint;
    Joint bottomRightJoint;
    Joint topLeftJoint;
    Joint headJoint;
    Joint neckJoint;

    //hand color position
    ColorSpacePoint leftHandPoint;
    ColorSpacePoint rightHandPoint;

    // Body reader
    IBodyFrameReader*       m_pBodyFrameReader;

    QCursor *cursor;

    int winx;
    int winy;



};

#endif // KINECTSENSOR_H
